import geopandas as gpd
import os
import pandas as pd
import matplotlib.pyplot as plt

# 将多个 GeoJSON 文件合并为一个 Shapefile 文件
# 文件目录和生成的目录都在当前目录下    
def merge_geojsons_to_shapefile(directory, output_shp):
    """
    合并指定目录下所有的 GeoJSON 文件到一个 Shapefile 文件中。

    :param directory: 包含 GeoJSON 文件的目录路径
    :param output_shp: 要保存的 Shapefile 文件的路径
    """
    all_gdfs = []
    # 遍历目录下的所有文件
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.endswith('.json'):
                file_path = os.path.join(root, file)
                try:
                    # 读取 GeoJSON 文件
                    gdf = gpd.read_file(file_path)
                    # 处理不支持的字段类型，将 object 类型的字段转换为字符串
                    for col in gdf.columns:
                        if gdf[col].dtype == 'object':
                            gdf[col] = gdf[col].astype(str)
                    # 处理过长的字段名
                    gdf.columns = [col[:10] if len(col) > 10 else col for col in gdf.columns]
                    all_gdfs.append(gdf)
                except Exception as e:
                    print(f"读取 {file_path} 时出错: {e}")
    
    if all_gdfs:
        # 合并所有 GeoDataFrame
        merged_gdf = gpd.GeoDataFrame(pd.concat(all_gdfs, ignore_index=True), crs=all_gdfs[0].crs)
        # 将合并后的 GeoDataFrame 保存为 Shapefile 文件
        merged_gdf.to_file(output_shp)
        print(f"成功将多个 GeoJSON 文件合并并保存为 Shapefile 文件，保存路径为: {output_shp}")
    else:
        print("未找到有效的 GeoJSON 文件。")

if __name__ == "__main__":
    # 指定包含 GeoJSON 文件的目录路径
    json_directory = '.'  # '.' 表示当前目录，可根据实际情况修改
    # 指定输出的 Shapefile 文件路径
    output_shp_path = 'merged_output.shp'
    merge_geojsons_to_shapefile(json_directory, output_shp_path)

    try:
        # 读取合并后的 Shapefile 文件
        merged_gdf = gpd.read_file(output_shp_path)
        # 绘制图形
        ax = merged_gdf.plot(figsize=(10, 10), edgecolor='black', facecolor='none')
        # 设置标题
        ax.set_title('Merged GeoJSON Data')
        # 显示图形
        plt.show()
    except Exception as e:
        print(f"可视化过程中出现错误: {e}")